<template>
  <div class="full" :style="{
    '--w': size.width,
    '--h': size.height
  }" @mousedown.left="(e) => {
  startSelect(e)
}" @mousemove="(e) => {
  if (e.buttons === 0 || !selects.length) {
    return
  }
  changeSelect(e)
}" @mouseup.left="(e) => {
  if (!selects.length) {
    return
  }
  endSelect(selects[selects.length - 1])
}" @touchstart="(e) => {
  startSelect(e.touches[0])
}" @touchmove="(e) => {
  e.preventDefault()
  if (e.touches.length === 0 || !selects.length) {
    return
  }
  changeSelect(e.touches[0])

}" @touchend="(e) => {
  if (!selects.length) {
    return
  }
  endSelect(selects[selects.length - 1])
}" @touchcancel="(e) => {
  if (!selects.length) {
    return
  }
  endSelect(selects[selects.length - 1])
}">
    <div class="main" ref="mainElement">
      <div class="row" v-for="i in Array.from({ length: size.height }, (_, index) => index)" :key="i">
        <div class="block" :class="{
          used: map[i][j].used
        }" :data-x="i" :data-y="j" v-for="j in Array.from({ length: size.width }, (_, index) => index)" :key="j">
          {{ map[i][j].value }}
        </div>
      </div>
      <div class="select" :class="{
        wrong: i.wrong,
        removed: i.removed
      }" :style="{
  '--start-x': i.startX,
  '--start-y': i.startY,
  '--end-x': i.endX,
  '--end-y': i.endY
}" v-for="i of selects" :key="i"></div>
    </div>
  </div>
</template>
<script setup>
import { reactive, ref, onMounted } from "vue"
const nowUrl = new URL(window.location.href)
function startSelect(data) {
  const p = getBlockPosition(data)
  selects.push({
    startX: p.x,
    startY: p.y,
    endX: p.x + 1,
    endY: p.y + 1,
    wrong: false,
    removed: false,
    startBlock: p
  })
  console.log(`start select ${p.x} ${p.y}`)
}
function changeSelect(data) {
  const p = getBlockPosition(data)
  const now = selects.length - 1
  selects[now].startX = Math.min(selects[now].startBlock.x, p.x)
  selects[now].startY = Math.min(selects[now].startBlock.y, p.y)
  selects[now].endX = Math.max(selects[now].startBlock.x, p.x) + 1
  selects[now].endY = Math.max(selects[now].startBlock.y, p.y) + 1
  console.log(`change select ${p.x} ${p.y}`)
}
/**@type {import("vue").Ref<HTMLDivElement>} */
const mainElement = ref()
function getPointerPosition(e) {
  const client = mainElement.value.getBoundingClientRect()
  return {
    x: Math.max(0, Math.min(e.pageX - client.left, client.width)),
    y: Math.max(0, Math.min(e.pageY - client.top, client.height)),
    client
  }
}
function getBlockPosition(e) {
  const p = getPointerPosition(e)
  const x = p.x / (p.client.width / size.width)
  const y = p.y / (p.client.height / size.height)
  return {
    x: Math.min(size.width - 1, parseInt(x) + (x - parseInt(x) > 0.95)),
    y: Math.min(size.height - 1, parseInt(y) + (y - parseInt(y) > 0.95)),
  }
}
function getSum(startX, startY, endX, endY) {
  let sum = 0
  for (let i = startX; i <= endX; i++) {
    for (let j = startY; j <= endY; j++) {
      if (map[j][i].used) {
        continue
      }
      sum += map[j][i].value
    }
  }
  return sum
}
function endSelect(e) {
  if (!e in selects) {
    return
  }
  setTimeout(() => {
    selects.splice(selects.indexOf(e), 1)
  }, 400);
  e.removed = true
  e.wrong=!select(e.startX, e.startY, e.endX - 1, e.endY - 1)
}
function select(startX, startY, endX, endY) {
  const sum = getSum(startX, startY, endX, endY)

  if (sum !== ans.value) {
    return false
  }
  for (let i = startX; i <= endX; i++) {
    for (let j = startY; j <= endY; j++) {
      map[j][i].used = true
    }
  }
  for (let i in map) {
    for (let j in map[i]) {
      if (!map[i][j].used) {
        return true
      }
    }
  }
  alert("WIN")
  return true
}
const size = reactive({
  width: 10,
  height: 10
})
const ans = ref(10)
/**@type {Array<{
  startX:number,
  startY:number,
  endX:number,
  endY:number,
  startBlock:{x:number,y:number},
  wrong:boolean,
  removed:boolean
}>} */
const selects = reactive([])
try {
  const w = parseInt(nowUrl.searchParams.get("w"), 10)
  size.width = Number.isNaN(w) || w < 1 ? 10 : w
} catch { }
try {
  const h = parseInt(nowUrl.searchParams.get("h"), 10)
  size.height = Number.isNaN(h) || h < 1 ? 10 : h
} catch { }
try {
  const a = parseInt(nowUrl.searchParams.get("a"), 10)
  ans.value = Number.isNaN(a) || a < 3 ? 10 : a
} catch { }
function randint(min, max) {
  return Math.floor(Math.random() * (max - min)) + min
}
const map = reactive(Array.from({ length: size.height }, (_, j) => Array.from({ length: size.width }, (_, i) => {
  return {
    used: false,
    value: randint(1, ans.value),
    x: i,
    y: j
  }
})))
function auto() {
  function search(x, y, startX, startY) {
    return new Promise((resolve, reject) => {
      console.log(x,y)

      const sum = getSum(startX, startY, x, y)

      if (sum === ans.value) {
        select(startX, startY, x, y)
        setTimeout(() => {
          resolve()
        },200)
        return
      }
      if (sum > ans) {
        reject()
      }
      if (y < size.height - 1) {
        setTimeout(()=>{
          search(x, y + 1, startX, startY).then(resolve,reject)
        },5)
      }
      if (x < size.width - 1) {
        setTimeout(()=>{
          search(x + 1, y, startX, startY).then(resolve,reject)
        },5)
      }
    })
  }
  for (let i = 0;i<map.length;i++) {
    for (let j=0;j<map[i].length;j++) {
      console.log(i,j)
      search(j,i,j,i)
    }
  }
  setTimeout(() => {
    auto()
  });
}
if (nowUrl.searchParams.get("auto") === 'zxqqypb') {
  setTimeout(() => {
    auto()
  });
}


</script>
<style scoped lang="scss">
.full {
  display: flex;
  position: fixed;
  inset: 0;
  justify-content: center;
  align-items: center;
  background-color: #0b0b0b;
  color: #fff;
}

.main,
.row {
  display: flex;
  flex-grow: 0;
  flex-shrink: 0;
}


$size: min(80vh / var(--h), 80vw / var(--w));
$row-gap: calc(10vh / (var(--h) - 1));
$col-gap: calc(10vw / (var(--w) - 1));


.main {
  flex-direction: column;
  position: relative;

  row-gap: $row-gap;
}

.row {
  column-gap: $col-gap;
  flex-direction: row;
}

$border-width: 2px;

.block {
  width: calc($size - 2 * $border-width);
  height: calc($size - 2 * $border-width);
  line-height: calc($size - 2 * $border-width);
  text-align: center;
  border-radius: 10%;
  font-size: calc($size / 2);
  background-color: transparent;
  user-select: none;
  transition: 0.3s;
  border: solid $border-width #003115;

  &:hover {
    background: #003115;
  }

  &.used {
    opacity: 0;
  }
}

.select {
  position: absolute;
  left: calc(#{$size} * var(--start-x) + #{$col-gap} * (var(--start-x)) - #{$border-width});
  top: calc(#{$size} * var(--start-y) + #{$row-gap} * (var(--start-y)) - #{$border-width});
  width: calc(#{$size} * (var(--end-x) - var(--start-x)) + #{$col-gap} * (var(--end-x) - var(--start-x) - 1) - #{$border-width});
  height: calc(#{$size} * (var(--end-y) - var(--start-y)) + #{$row-gap} * (var(--end-y) - var(--start-y) - 1) - #{$border-width});
  background-color: rgba(70, 70, 255, 0.2);
  pointer-events: none;
  border: solid $border-width #00f;
  transition: all 0.3s, border-color 0s, background-color 0s;

  &.removed {
    opacity: 0;
  }

  &.wrong {
    background-color: rgba(255, 70, 70, 0.2);
    border: solid $border-width #f00;
  }
}
</style>